Golang高性能日志库zap + lumberjack 日志切割组件详解

您所在的位置:网站首页 presto logger 伐木工 Golang高性能日志库zap + lumberjack 日志切割组件详解

Golang高性能日志库zap + lumberjack 日志切割组件详解

2024-07-10 07:43| 来源: 网络整理| 查看: 265

文章篇幅较长,可以先收藏防止迷路~

目录 zap日志库1. why zap?2. 简单使用3. 自定义logger例子4. Gin项目使用zap6. lumberjack 日志切割组件

zap日志库

在许多Go语言项目中,我们需要一个好的日志记录器能够提供下面这些功能:

能够将事件记录到文件中,而不是应用程序控制台;日志切割-能够根据文件大小、时间或间隔等来切割日志文件;支持不同的日志级别。例如INFO,DEBUG,ERROR等;能够打印基本信息,如调用文件/函数名和行号,日志时间等; 1. why zap?

比较全的日志级别

支持结构化日志

性能

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RKcZFu8o-1662037156664)(images/image-20220901184049353.png)]

2. 简单使用 go get -u go.uber.org/zap

Zap提供了两种类型的日志记录器 — Sugared Logger 和 Logger

Sugared Logger 并重性能与易用性,支持结构化和 printf 风格的日志记录。

Logger 非常强调性能,不提供 printf 风格的 api (减少了 interface{} 与 反射的性能损耗),如下例子:

func main() { // sugared sugar := zap.NewExample().Sugar() sugar.Infof("hello! name:%s,age:%d", "xiaomin", 20) // printf 风格,易用性 // logger logger := zap.NewExample() logger.Info("hello!", zap.String("name", "xiaomin"), zap.Int("age", 20)) // 强调性能 }

输出结果:

// output {"level":"info","msg":"hello! name:xiaomin,age:20"} {"level":"info","msg":"hello!","name":"xiaomin","age":20}

zap 有三种默认配置创建出一个 logger,分别为 example,development,production,示例:

func main() { // example logger := zap.NewExample() logger.Info("example") // Development logger,_ = zap.NewDevelopment() logger.Info("Development") // Production logger,_ = zap.NewProduction() logger.Info("Production") }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qbe0kc6L-1662037156665)(images/image-20220901184439347.png)]

可以看出:日志等级,日志输出格式,默认字段都有所差异。

也可以自定义 logger,如下:

func main() { encoder := getEncoder() sync := getWriteSync() core := zapcore.NewCore(encoder, sync, zapcore.InfoLevel) logger := zap.New(core) logger.Info("info 日志",zap.Int("line", 1)) logger.Error("info 日志", zap.Int("line", 2)) } // 负责设置 encoding 的日志格式 func getEncoder() zapcore.Encoder { return zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()) } // 负责日志写入的位置 func getWriteSync() zapcore.WriteSyncer { file, _ := os.OpenFile("./log.txt", os.O_CREATE|os.O_APPEND|os.O_RDWR, os.ModePerm) syncFile := zapcore.AddSync(file) syncConsole := zapcore.AddSync(os.Stderr) return zapcore.NewMultiWriteSyncer(syncConsole, syncFile) }

运行结果:

// output // 创建 log.txt,追加日志 // console 打印日志 //{"level":"info","ts":1636471657.16419,"msg":"info 日志","line":1} //{"level":"error","ts":1636471657.1643898,"msg":"info 日志","line":2}

从 New(core zapcore.Core, options ...Option) *Logger 出发,需要构造 zapcore.Core

通过 NewCore(enc Encoder, ws WriteSyncer, enab LevelEnabler) Core 方法,又需要传入三个参数 Encoder : 负责设置 encoding 的日志格式, 可以设置 json 或者 text结构,也可以自定义json中 key 值,时间格式…ws WriteSyncer: 负责日志写入的位置,上述例子往 file 与 console 同时写入,这里也可以写入网络。LevelEnabler: 设置日志记录级别 3. 自定义logger例子

./util/zap.go

定义结构体:

package util import ( "net" "net/http" "net/http/httputil" "os" "runtime/debug" "strings" "time" "github.com/gin-gonic/gin" "github.com/natefinch/lumberjack" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) type LogConfig struct { Level string `json:"level"` // Level 最低日志等级,DEBUG= MaxSize 兆字节,则通过将当前时间放在文件扩展名之前的名称中的时间戳中来重命名文件(如果没有扩展名,则放在文件名的末尾)。然后使用原始文件名创建一个新的日志文件。

每当写入会导致当前日志文件超过 MaxSize 兆字节时,当前文件将被关闭、重命名,并使用原始名称创建新的日志文件。因此,你给 Logger 的文件名始终是“当前”日志文件。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sVRrlpF1-1662037156666)(images/image-20220901205644931.png)]

可以看到,原文件写到MaxSize大小之后,会被重命名,格式为:原文件名+当前时间(时间格式为time.Time 格式),而创建一个新的文件,命名为原文件名。

备份

备份使用提供给 Logger 的日志文件名,格式为 name-timestamp.ext 其中 name 是不带扩展名的文件名,timestamp 是使用 time.Time 格式格式化的日志轮换时间2006-01-02T15-04-05.000,扩展名ext是原始扩展名。

例如,如果您的 Logger.Filename 是/var/log/foo/server.log,则在 2016 年 11 月 11 日下午 6:30 创建的备份将使用文件名 /var/log/foo/server-2016- 11-04T18-30-00.000.log

清理旧的日志文件 每当创建新的日志文件时,可能会删除旧的日志文件。根据编码时间戳的最新文件将被保留,最多等于 MaxBackups 的数量(如果 MaxBackups 为 0,则保留所有文件)。无论 MaxBackups 是什么,任何编码时间戳早于 MaxAge 天的文件都会被删除。请注意,时间戳中编码的时间是轮换时间,可能与上次写入该文件的时间不同。

如果 MaxBackups 和 MaxAge 都为 0,则不会删除旧的日志文件。

type Logger struct { // Filename 写入日志的文件。备份的日志文件将保留在同一目录下。 // 如果为空,则在os.TempDir()中使用-lumberjack.log。 Filename string `json:"filename" yaml:"filename"` // MaxSize 是日志文件在轮换之前的最大大小(以 MB 为单位)。默认为 100 兆字节。 MaxSize int `json:"maxsize" yaml:"maxsize"` // MaxAge 是根据文件名中编码的时间戳保留旧日志文件的最大天数。 // 请注意,一天被定义为 24 小时,由于夏令时、闰秒等原因,可能与日历日不完全对应。 // 默认情况下不会根据年龄删除旧日志文件。 MaxAge int `json:"maxage" yaml:"maxage"` // MaxBackups 是要保留的旧日志文件的最大数量。 // 默认是保留所有旧的日志文件(尽管 MaxAge 可能仍会导致它们被删除。) MaxBackups int `json:"maxbackups" yaml:"maxbackups"` // LocalTime 确定用于格式化备份文件中时间戳的时间是否是计算机的本地时间。默认是使用 UTC 时间。 LocalTime bool `json:"localtime" yaml:"localtime"` // Compress 确定是否应使用 gzip 压缩旋转的日志文件。默认是不执行压缩。 Compress bool `json:"compress" yaml:"compress"` ... }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3